/**
 * 项目名：五位一体化工安全信息平台
 * 日期：    2019-11-25 13:04:58
 * Copyright (c) 2015- joysuch-版权所有
 */

package com.joysuch.wwyt.core.controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import javax.validation.constraints.Pattern;

import cn.zlg.common.springmvc.validate.constraints.NotNull;
import com.joysuch.wwyt.bp.service.BpContractorStaffService;
import com.joysuch.wwyt.core.bean.*;
import com.joysuch.wwyt.core.common.ajax.ResultBean;
import com.joysuch.wwyt.core.constant.Constants;
import com.joysuch.wwyt.core.entity.BaseLoginAccount;
import com.joysuch.wwyt.core.entity.BaseUser;
import com.joysuch.wwyt.core.enums.LoginUserStates;
import com.joysuch.wwyt.core.enums.Status;
import com.joysuch.wwyt.core.repository.BaseLoginAccountDao;
import com.joysuch.wwyt.core.security.ShiroUser;
import com.joysuch.wwyt.core.service.BaseLoginAccountService;
import com.joysuch.wwyt.core.service.BaseUserService;
import com.joysuch.wwyt.core.service.SimpleSelectListService;
import com.joysuch.wwyt.core.support.Context;
import com.joysuch.wwyt.edu.bean.EduCertUserDto;
import com.joysuch.wwyt.edu.bean.EduCertUserQueryBean;
import com.joysuch.wwyt.repeatsubmit.NoRepeatSubmit;
import com.joysuch.wwyt.util.PageableUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Assert;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.querydsl.QPageRequest;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;

@RestController
@RequestMapping("/base/user")
@Api(tags = "/base/user 用户")
public class BaseUserController {

    private static final Logger logger = LoggerFactory.getLogger(BaseUserController.class);

    @Autowired
    private BaseLoginAccountService loginAccountService;
    @Autowired
    private BaseUserService baseUserService;
    @Autowired
    private SimpleSelectListService simpleSelectListService;
    @Autowired
    private BaseLoginAccountDao accountDao;
    @Autowired
    private BpContractorStaffService bpContractorStaffService;

    @PostMapping("add")
    @ApiOperation("新增")
    @NoRepeatSubmit(paramNames = "code")
    public Object add(@RequestBody @Valid BpUserListBean entity) throws Exception {
        return baseUserService.add(entity);
    }

    @PostMapping("update")
    @ApiOperation("修改")
    public Object update(@RequestBody @Valid BpUserListBean entity) throws Exception {
        if (entity.getId() == null) {
            return ResultBean.fail(102, "未指定主键");
        }
        return baseUserService.update(entity);
    }

    @GetMapping("page")
    @RequiresPermissions("bp:enterprise:staff")
    public ResultBean page(Integer page, Integer size, BpUserSearchBean bpUserSearchBean, Long chiefId) {
        try {
            Page<BaseUserFindAllBean> byPage = baseUserService.findByPage(QPageRequest.of(page, size), bpUserSearchBean,
                    chiefId);
            // return ResultBean.
            return ResultBean.pageData(byPage.getContent(), byPage.getTotalElements());
        } catch (Exception e) {
            logger.error("分页查询失败", e);
            return ResultBean.fail(101, "分页查询失败");
        }
    }

    @GetMapping("/getRole")
    public ResultBean getRole(Long role) {
        List<BaseUserFindAllBean> role1 = baseUserService.getRole(role);
        return ResultBean.wrapSuccessfulResult(role1);
    }

    @PostMapping("/setShowNumber")
    @ApiOperation("设置显示顺序")
    @RequiresPermissions("base:user:setShowNumber")
    public ResultBean setShowNumber(@RequestBody List<BaseUserFindAllBean> list) {
        baseUserService.setShowNumber(list);
        return ResultBean.success("");
    }

    @GetMapping("getUset")
    public List<BpUserBean> getUset(String name, Long typeId) {
        List<BpUserBean> uset = baseUserService.getUset(name, typeId);
        return uset;
    }

    @GetMapping("getById")
    public ResultBean gtById(Long userId) {
        BpUserListBean byId = baseUserService.findById(userId);
        return ResultBean.wrapSuccessfulResult(byId);
    }

    @RequestMapping("delete")
    @ApiOperation("删除")
    public ResultBean delete(Long id) {
        baseUserService.delete(id);
        return ResultBean.success("");
    }

    @RequestMapping("detail-list")
    @ApiOperation("用户模板")
    public Object detailList(Pageable page, BaseUserListSearchBean condition) {
        Page<BaseUserListBean> data = baseUserService.findDetailInfoByPage(page, condition);
        return ResultBean.pageData(data.getContent(), data.getTotalElements());
    }

    @RequestMapping("user-simple-list")
    @ApiOperation("用户列表")
    public Object findUserSimpleList(Integer userContractorFlag) {
        List<SimpleUserBean> data = baseUserService.findUserSimpleList(userContractorFlag);
        return ResultBean.success(data);
    }

    @RequestMapping("user-list-with-exam-score")
    public Object getUserListWithExamScore(Pageable page, BaseUserListSearchBean condition, Long examId) {
        Page<BaseUserListBean> data = baseUserService.findDetailInfoWithExamScoreByPage(page, condition, examId);
        return ResultBean.pageData(data.getContent(), data.getTotalElements());
    }

    @RequestMapping("simple-list")
    public Object simpleList() {
        try {
            List<SimpleSelectListBean> data = baseUserService.getUserSimpleList();
            // List<SimpleSelectListBean> data = simpleSelectListService.list(BaseUser.class, "realName");
            return ResultBean.success(data);
        } catch (Exception e) {
            logger.error("分页查询失败", e);
            return ResultBean.fail(101, "分页查询失败");
        }
    }

    // 未用到的接口
    @RequestMapping("simple-page")
    public Object simplePage(Pageable pageList) {
        try {
            Page<SimpleSelectListBean> data = simpleSelectListService.page(pageList, BaseUser.class, "realName");
            return ResultBean.pageData(data);
        } catch (Exception e) {
            logger.error("分页查询失败", e);
            return ResultBean.fail(101, "分页查询失败");
        }
    }

    @GetMapping("getJob")
    public ResultBean job() {
        List<BpJobBean> job = baseUserService.getJob();
        return ResultBean.wrapSuccessfulResult(job);
    }

    /**
     * 根据部门id 查询关联的岗位
     *
     * @param departId
     * @return
     */
    @GetMapping("getNewJob")
    public ResultBean getNewJob(Long departId) {
        List<BpJobBean> job = baseUserService.getNewJob(departId);
        return ResultBean.wrapSuccessfulResult(job);
    }

    @GetMapping("getWorkType")
    public ResultBean workType() {
        List<BpWorkTypeBean> workType = baseUserService.getWorkType();
        return ResultBean.wrapSuccessfulResult(workType);
    }

    @GetMapping("getDepart")
    public ResultBean getDepart() {
        List<BpDepartBean> workType = baseUserService.getDepart();
        return ResultBean.wrapSuccessfulResult(workType);
    }

    /**
     * 根据岗位id 查询关联的部门
     *
     * @param jobId
     * @return
     */
    @GetMapping("getNewDepart")
    public ResultBean getNewDepart(Long jobId) {
        List<BpDepartBean> workType = baseUserService.getNewDepart(jobId);
        return ResultBean.wrapSuccessfulResult(workType);
    }


    // 没用到的借口
    @GetMapping("getAllUser")
    public ResultBean getAllUser(@RequestParam(value = "name", defaultValue = "") String name,
                                 @RequestParam(value = "departName", defaultValue = "") String departName,
                                 @RequestParam(value = "type", defaultValue = "0") Integer type,
                                 @RequestParam(value = "page", defaultValue = "1") Integer page,
                                 @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
        if (page < 1)
            page = 1;
        if (pageSize < 1)
            pageSize = 10;
        if (type < 0 || type > 2)
            type = 0;
        name = name.trim();
        departName = departName.trim();
        int userTotal = baseUserService.getAllUserTotalCount(name, departName, type);
        if (userTotal <= 0)
            return ResultBean.wrapSuccessfulResult(null);
        List<Map<String, Object>> userList = baseUserService.getAllUser(name, departName, type, page, pageSize);
        Map<String, Object> data = new HashMap<>();
        data.put("userTotal", userTotal);
        data.put("userList", userList);
        return ResultBean.wrapSuccessfulResult(data);
    }

    // 添加用户账户接口
    @ResponseBody
    @RequestMapping("/addLogin")
    public ResultBean addLogin(@RequestBody BaseLoginAccount bean) throws Exception {
        bean.setState(LoginUserStates.NORMAL.getCode());
        String save = loginAccountService.save(bean);
        return ResultBean.success(save);
    }

    // 查询用户账户接口
    @ResponseBody
    @GetMapping("/getLogin")
    public ResultBean getLogin(Long id) {
        BaseLoginAccount a = loginAccountService.findById(id);
        if (a != null) {
            BaseLoginAccountBean s = new BaseLoginAccountBean();
            s.setUserName(a.getUserName());
            return ResultBean.wrapSuccessfulResult(s);
        } else {
            BaseLoginAccountBean s = new BaseLoginAccountBean();
            s.setUserName(null);
            return ResultBean.success(s);
        }
    }

    @ApiOperation("是否需要弹出签名")
    @GetMapping("/need/autograph")
    public ResultBean needAutograph() {
        boolean b = baseUserService.needAutograph(Context.getCurrentUserId());
        return ResultBean.success(b);
    }

    @ApiOperation("更新签名")
    @RequestMapping("/update/autograph")
    public ResultBean updateAutograph(String autograph, String flowSignature) {
        baseUserService.updateAutograph(autograph, flowSignature, Context.getCurrentUserId());
        return ResultBean.defaultSuccessResult();
    }


    // 修改用户账户接口
    @ResponseBody
    @PostMapping("/edit")
    @ApiOperation("用户账户修改")
    public ResultBean edit(@RequestBody BaseLoginAccount bean) {
        bean.setState(LoginUserStates.NORMAL.getCode());
        String save = loginAccountService.edit(bean);
        return ResultBean.success(save);
    }

    // 开启,关闭账户
    @ResponseBody
    @GetMapping("/setLoginAccount")
    @ApiOperation("开启,关闭账户")
    @RequiresPermissions("base:user:setLoginAccount")
    public ResultBean setLoginAccount(Long userId, Integer showState) {
        loginAccountService.setLoginAccount(userId, showState);
        return ResultBean.success("");
    }

    @ResponseBody
    @PostMapping("getAccount")
    public ResultBean createLoginAccountIfNotExists(@RequestBody BaseLoginAccount bean, HttpServletRequest request) {
        BaseLoginAccount byBaseUser = accountDao.findByBaseUser(bean.getBaseUser());

        UsernamePasswordTokenWithCompanyCode token = new UsernamePasswordTokenWithCompanyCode(byBaseUser.getUserName(),
                byBaseUser.getPassword());
        Subject subject = SecurityUtils.getSubject();
        try {
            // token.setRememberMe(true);
            String companyCode = findCompanyCode(request);
            token.setCompanyCode(companyCode);
            subject.login(token);// 登陆成功的话，放到session中
            ShiroUser user = (ShiroUser) subject.getPrincipal();
            baseUserService.completeShiroUserInfo(user.getRealUserId(), user);
            // 设置公司编码
            user.setCompanyCode(companyCode);
            request.getSession().setAttribute("user", user);
            return ResultBean.success("");
        } catch (Exception e) {
            return ResultBean.fail(101, "验证失败");
        }
    }

    ModelAndView loginSuccess(HttpServletRequest request) {
        ModelAndView mav = new ModelAndView();
        MappingJackson2JsonView view = new MappingJackson2JsonView();
        view.setAttributesMap(ResultBean.successInMap(null));
        mav.setView(view);
        return mav;
        // if (HttpUtils.isAjaxRequest(request)) {
        // } else {
        // return new ModelAndView("/index");
        // }
    }

    private String findCompanyCode(HttpServletRequest request) {
        String companyCode = null;
        if (request.getParameter(Constants.COMPANY_CODE) != null) {
            companyCode = request.getParameter(Constants.COMPANY_CODE);
        } else if (request.getHeader(Constants.COMPANY_CODE) != null) {
            companyCode = request.getHeader(Constants.COMPANY_CODE);
        } else {
            Cookie[] cookies = request.getCookies();
            if (cookies != null) {
                for (Cookie c : cookies) {
                    if (c.getName().equals(Constants.COMPANY_CODE)) {
                        // user.setCompanyCode(c.getValue());
                        companyCode = c.getValue();
                        break;
                    }
                }
            }
        }
        if (companyCode == null) {
            companyCode = findCompanyCodeFromDomain(request.getServerName());
        }
        if (companyCode == null) {
            throw new IllegalStateException("找不到有效的厂区信息");
        }
        return companyCode;
    }

    private String findCompanyCodeFromDomain(String serverName) {
        // TODO Auto-generated method stub
        return null;
    }

    @PostMapping("getPwdBack")
    @ApiOperation("找回密码")
    public ResultBean getPwdBack(@RequestBody @Valid BaseUserPwdDto baseUserPwdDto) {
        return baseUserService.getPwdBack(baseUserPwdDto);
    }

    @PostMapping("auditPwd")
    @ApiOperation("验证码验证")
    public ResultBean auditPwd(@RequestBody @Valid BaseUserPwdDto baseUserPwdDto) {
        return baseUserService.auditPwd(baseUserPwdDto);
    }

    @PostMapping("editPwd")
    @ApiOperation("找回密码-修改密码")
    public ResultBean editPwd(@RequestBody @Valid BaseUserPwdDto baseUserPwdDto) {
        return baseUserService.editPwd(baseUserPwdDto);
    }

    @GetMapping("getIdByName")
    @ApiOperation("根据名称查询用户Id")
    public ResultBean getIdByName(String name) {
        return baseUserService.getIdByName(name);
    }

    @GetMapping("getDepartDutyUserById")
    @ApiOperation("根据用户Id获取所在部门负责人信息")
    public ResultBean getDepartDutyUserById(Long id) {
        return ResultBean.success(baseUserService.getDepartDutyUser(id));
    }

    @PostMapping("locate-sync-user/{flag}")
    @ApiOperation("人员在岗在位-同步人员")
    @ApiImplicitParam(name = "flag", value = "1 同步所有人员; 0 同步部分人员", paramType = "path", required = true)
    @RequiresPermissions("base:user:locate-sync-user")
    public ResultBean locateSyncUser(@PathVariable Integer flag, @RequestBody List<Long> userIds) {
        return baseUserService.locateSyncUser(flag, userIds);
    }

    @GetMapping("getCreditCardRecord")
    @ApiOperation("卡口信息")
    public ResultBean getCreditCardRecord(Pageable page, BaseCreditCardRecordSearchBean condition) {
        Page<BaseCreditCardRecordBean> p = baseUserService.getCreditCardRecord(page, condition);
        return ResultBean.pageData(p.getContent(), p.getTotalElements());
    }

    @GetMapping("getCreditCardUserDetail")
    @ApiOperation("卡口人员信息详情")
    public ResultBean getCreditCardUserDetail(Integer typeFlag, String code) {
        return baseUserService.getCreditCardUserDetail(typeFlag, code);
    }

    @GetMapping("editAlarmTemplate")
    // @RequiresPermissions("bp:user:editAlarmTemplate")
    @ApiOperation("添加人员报警模板")
    public ResultBean editAlarmTemplate(Long userId, Long templateId, String templateName) {
        BaseUser user = baseUserService.editAlarmTemplate(userId, templateId, templateName);
        return ResultBean.success(user.getId());
    }

    @GetMapping("getIdBySn")
    @ApiOperation("根据sn查人员id")
    public ResultBean getIdBySn(String sn, Integer type) {
        Assert.notNull(sn, "sn cannot be null");
        // 0本公司人员 1承包商
        if (type != null && type.intValue() == 0) {
            return baseUserService.getIdBySn(sn);
        } else if (type != null && type.intValue() == 1) {
            return bpContractorStaffService.getIdBySn(sn);
        } else {
            return ResultBean.success("");
        }

    }

    @PostMapping("findUserInfoByCardNumber")
    @ApiOperation("根据门禁卡号获取人员信息")
    @ApiImplicitParam(name = "userContractorFlag", value = "true 承包商，默认普通人员", paramType = "boolean")
    public ResultBean findUserInfoByCardNumber(@RequestBody BaseNFCSelectUserBean bean) {
        BaseUserCardNumBean userCard = baseUserService.findUserInfoByCardNumber(bean.getCertIds(), bean.getCardNumber(),
                bean.getUserContractorFlag());
        if (userCard != null) {
            return ResultBean.success(userCard);
        } else {
            return ResultBean.fail(Status.USER_NOT_FIND);
        }
    }

    @RequestMapping("batch-upload-id-image")
    @ApiOperation("批量导入证件照片")
    @ResponseBody
    public Object batchUploadCertImages(MultipartFile file,
                                        @Valid @NotNull(field = "匹配类型") @Pattern(regexp = "name|sn|code") String type) {
        BatchUploadResult result = baseUserService.batchUploadIdImages(file, type);
        return ResultBean.success(result);
    }

    @RequestMapping("userPage")
    @ApiOperation("人员和承包商人员分页查询")
    public ResultBean certPage(EduCertUserQueryBean bean, Pageable pageable) {
        List<EduCertUserDto> resultList = PageableUtil.getList(pageable, baseUserService.getUserOrContractorUserList(bean));
        int count = baseUserService.getUserOrContractorUserCount(bean);
        return ResultBean.pageData(resultList, count);
    }

    @PostMapping("/findUserByJobIds")
    @ApiOperation(value = "根据岗位id获取此岗位下的所有人")
    public ResultBean findUserByJobId(@RequestBody List<Long> jobIds) {
        return ResultBean.success(baseUserService.findUserByJobIds(jobIds));
    }

    @PostMapping("syncFace")
    @ApiOperation("同步人脸")
    public ResultBean syncFace(@RequestBody List<Long> ids) {
        return baseUserService.syncFace(ids);
    }

    @PostMapping("/findUserByDeparts")
    @ApiOperation(value = "根据部门岗位id获取所有人")
    public ResultBean findUserByDepart(@RequestBody BaseUserDepartJobBean bean) {
        return ResultBean.success(baseUserService.findUserByDepart(bean));
    }
}
